package com.bocai.grainshop.ware.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bocai.common.to.mq.StockDetailTo;
import com.bocai.common.to.mq.StockLockedTo;
import com.bocai.common.to.mq.WareOrdersn;
import com.bocai.common.utils.R;
import com.bocai.grainshop.ware.dao.WareSkuDao;
import com.bocai.grainshop.ware.entity.WareOrderTaskDetailEntity;
import com.bocai.grainshop.ware.entity.WareOrderTaskEntity;
import com.bocai.grainshop.ware.feign.OrderFeignService;
import com.bocai.grainshop.ware.service.impl.WareOrderTaskDetailServiceImpl;
import com.bocai.grainshop.ware.service.impl.WareOrderTaskServiceImpl;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;

@Service
@Slf4j
//监听rabbitmq的队列
@RabbitListener(queues = "stock.release.stock.queue")
public class RabbitLockWareListener {

    @Autowired
    private WareOrderTaskDetailServiceImpl wareOrderTaskDetailService;

    @Autowired
    private WareOrderTaskServiceImpl wareOrderTaskService;

    @Autowired
    private OrderFeignService orderFeignService;

    @Resource
    private WareSkuDao wareSkuDao;
    /**
     * @Author: SunJinbo
     * @Description  监听到消息,解锁库存的回调 库存解锁队列延迟高于订单
     * 如果回调解锁方法失败  一定告诉rabbitmq 消息不要删  手动ack模式
     * @Param [stockLockedTo]
     * @return void
     * @Data Created in 2022/4/24 20:58
     */
    @RabbitHandler
    public void HanderStockWareRelease(StockLockedTo stockLockedTo, Message message, Channel channel) throws IOException {
        log.info("收到消息队列的信息{}"+message.toString());
        Long id = stockLockedTo.getId();
        StockDetailTo detailTo = stockLockedTo.getDetailTo();
        //解锁:  1.用户下单成功 锁定库存失败 库存回滚 无锁定单信息  无需解锁
        //      2.库存锁定成功! 手续发送异常 库存无法单击回滚 有锁定信息单 需要解锁
        //         继续判断 是否有订单? 如果没有,必须解锁库存
        //         有继续判断支付状态,为已取消解锁库存,没取消不能解锁
        WareOrderTaskDetailEntity byId = wareOrderTaskDetailService.getById(detailTo.getId());
        if(byId != null && byId.getLockStatus() != 2){
            //通过工号单的id 查询订单号
            WareOrderTaskEntity orderTaskEntity = wareOrderTaskService.getById(id);
            //解锁  远程查询是否有订单
            R orderSn = orderFeignService.getInfoByOrderSn(orderTaskEntity.getOrderSn());
            Object code = orderSn.get("code");
            String s = JSON.toJSONString(code);
            Integer codeNum = JSON.parseObject(s, new TypeReference<Integer>() {
            });
            if(codeNum == 0){
                //远程调用成功 查询到订单
                Object statu = orderSn.get("status");
                String toJSONString = JSON.toJSONString(statu);
                Integer status = JSON.parseObject(toJSONString, new TypeReference<Integer>() {
                });
                if(status == 5 || status == 4){
                    //如果这个订单是无效 解锁库存
                    //TODO 解锁库存
                    wareSkuDao.unLockWare(byId.getSkuId(),byId.getWareId(),byId.getSkuNum());
                    //TODO 修改工作单
                    updateWareOrderTaskDetail(byId);
                    //TODO 解锁成功  回复手动ack
                    log.info("第一次解锁--》");
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                }else{
                    //TODO 模拟网络波动  关单超时
                    log.info("订单状态正常 直接ack----》");
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                }
            }else {
                //TODO 解锁库存
                wareSkuDao.unLockWare(byId.getSkuId(),byId.getWareId(),byId.getSkuNum());
                //TODO 修改工作单
                updateWareOrderTaskDetail(byId);
                //TODO 没有订单 更需要解锁库存 回复手动ack
                log.info("第二次解锁--》");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            }
        }else {
            //TODO  订单已解锁,将原来存库锁定的消息签收即可
            log.info("第三次解锁--》");
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        }
    }

    /**
     * @Author: SunJinbo
     * @Description  接受的对象 必须是同一个包 防止订单解锁超时
     * @Param [OrderSn, message, channel]
     * @return void
     * @Data Created in 2022/4/25 21:19
     */
    @RabbitHandler
    public void HanderLisntenerOrderClose(WareOrdersn OrderSn, Message message, Channel channel) throws IOException {
        log.info("监听到订单完成关单发送来的消息-》》》订单号{}"+OrderSn);
        try {
            unLockeWare(OrderSn.getOrderSn());
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            log.info("发送异常---->");
            channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
        }
    }

    //解锁库存
    @Transactional
    public void unLockeWare(String orderSn) {
        WareOrderTaskEntity order_sn = wareOrderTaskService.getOne(new QueryWrapper<WareOrderTaskEntity>().eq("order_sn", orderSn));
        List<WareOrderTaskDetailEntity> list = wareOrderTaskDetailService.list(new QueryWrapper<WareOrderTaskDetailEntity>().eq("task_id", order_sn.getId()).eq("lock_status", 1));
        list.forEach(o->{
            wareSkuDao.unLockWare(o.getSkuId(),o.getWareId(),o.getSkuNum());
            updateWareOrderTaskDetail(o);
        });
    }

    //修改工作单
    private void updateWareOrderTaskDetail(WareOrderTaskDetailEntity byId) {
        WareOrderTaskDetailEntity detailEntity = new WareOrderTaskDetailEntity();
        BeanUtils.copyProperties(byId,detailEntity);
        detailEntity.setLockStatus(2);
        wareOrderTaskDetailService.updateById(detailEntity);
    }


}
